package com.yun.zhong.fu.usercenter.aspect;

import com.yun.zhong.fu.usercenter.jwt.JwtOperator;
import io.jsonwebtoken.Claims;
import lombok.RequiredArgsConstructor;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

/**
 * @Author RenPu
 * @Date 2021/1/5 16:04
 * @Version 1.0
 * @Description: 自定义切面类
 **/
@Aspect
@Component
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class DefeinationAspect {
    private final JwtOperator jwtOperator;


    //环绕增强，只要是被CheckLog修饰的方法，在执行方法前都会进入此切入点进行行方法校验
    @Around("@annotation(com.yun.zhong.fu.usercenter.annation.CheckLog)")
    public Object checkLog(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        //验证token是否合法
        this.checkLog();
        return proceedingJoinPoint.proceed();
    }






    //验证token是否有效以及将用户的数据封装到request对象里
    private void checkLog() {

        //1:从header里获取token
        //获取request对象（spring mvc获取request对象的方式）
        HttpServletRequest request = this.getHttpRequest();
        //获取token值
        String token = request.getHeader("X-Token");
        //2:验证token是否合法
        Boolean aBoolean = jwtOperator.validateToken(token);
        if (!aBoolean) {
            throw new SecurityException("Token 不合法...");
        }
        //3：将token携带的用户信息进行封装到request的attributes里
        Claims claimsFromToken = jwtOperator.getClaimsFromToken(token);
        request.setAttribute("id", claimsFromToken.get("id"));
        request.setAttribute("wxNickname", claimsFromToken.get("wxNickname"));
        request.setAttribute("role", claimsFromToken.get("role"));
    }



    //封装spring mvc获取request对象的方法
    private HttpServletRequest getHttpRequest() {
        //获取request对象（spring mvc获取request对象的方式）
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes requestAttributes1 = (ServletRequestAttributes) requestAttributes;
        HttpServletRequest request = requestAttributes1.getRequest();
        return request;
    }




}
